package com.lxq.live.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import com.lxq.live.dao.RedisVerificationCode;
import com.lxq.live.pojo.NewResetEnum;
import com.lxq.live.pojo.User;
import com.lxq.live.pojo.VideoRow;
import com.lxq.live.service.LiveMailService;
import com.lxq.live.service.ResetPasswordService;
import com.lxq.live.service.UserService;
import com.lxq.live.service.VideoService;
import com.lxq.live.util.CommonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(tags = "用户接口")
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    CommonUtil commonUtil;
    @Autowired
    VideoService videoService;
    @Autowired
    LiveMailService mailService;
    @Autowired
    ResetPasswordService resetPasswordService;
    @Autowired
    RedisVerificationCode redisVerificationCode;

    @GetMapping("/is_login")
    public String isLogin(HttpSession session) {
        var objectMapper = new ObjectMapper();
        var objectNode = objectMapper.createObjectNode();
        String userSession = (String) session.getAttribute(session.getId());
        if (userSession != null) {
            objectNode.put("isLogin", true);
            objectNode.put("userId", userSession);
            objectNode.put("userName", getUserInfo(session).getUserName());
        } else {
            objectNode.put("isLogin", false);
        }
        return objectNode.toString();
    }

    @GetMapping("/user/get_user_info")
    public User getUserInfo(HttpSession httpSession) {
        var user = userService.findByUserId(httpSession.getAttribute(httpSession.getId()) + "");
        if (user != null) {
            user.setPassword("DO NOT");
        }
        return user;
    }

    @PostMapping("/user/upload_video")
    public HashMap<String, Object> uploadVideo(MultipartFile videoFile, MultipartFile coverImg,//需要优化
                                               HttpServletRequest request, HttpSession session) throws IOException {
        var resultMap = new HashMap<String, Object>();
        var userId = session.getAttribute(session.getId());
        var relatePathOfUser = commonUtil.getRelatePathOfUser(userId + "");
        var uuid = commonUtil.getUUID();
        var userIdZonePath = CommonUtil.VIRTUAL_USER + userId + "/" + uuid + "/";
        commonUtil.checkAndMKDir(userIdZonePath);
        var videoSuffix = videoFile.getOriginalFilename() == null ? ".mp4" : videoFile.getOriginalFilename();
        videoSuffix = videoSuffix.substring(videoSuffix.lastIndexOf("."));
        var saveVideoPath = userIdZonePath + uuid + videoSuffix;
        var saveCoverPath = userIdZonePath + uuid + ".jpg";
        videoFile.transferTo(new File(saveVideoPath));
        var objMapper = new ObjectMapper();
//        System.out.println(request.getParameter("fileAttach"));
        var imgSuffix = ".jpg";
        var jsonNode = objMapper.readTree(request.getParameter("fileAttach"));
        if (jsonNode.path("videoCoverWay").asInt() == 1) {
            imgSuffix = coverImg.getOriginalFilename() == null ? ".jpg" : coverImg.getOriginalFilename();
            imgSuffix = imgSuffix.substring(imgSuffix.lastIndexOf("."));
            saveCoverPath = userIdZonePath + uuid + imgSuffix;
            coverImg.transferTo(new File(saveCoverPath));
            resultMap.put("upload_result", true);
        } else if (jsonNode.path("videoCoverWay").asInt() == 2) {
            var result = commonUtil.generateScreenShot(saveVideoPath, saveCoverPath,
                    jsonNode.path("videoSolution").asInt());
            resultMap.put("upload_result", result);
        } else {
            var result = commonUtil.generateScreenShot(saveVideoPath, saveCoverPath, 5);
            resultMap.put("upload_result", result);
        }
        var videoRow = new VideoRow();
        videoRow.setTitle(jsonNode.path("videoTitle").asText());
        videoRow.setDescription(jsonNode.path("videoDescription").asText());
        videoRow.setUuid(uuid);
        videoRow.setAuthorId(userId + "");
        videoRow.setFilePath(saveVideoPath);
        videoRow.setVideoUrl(relatePathOfUser + uuid + "/" + uuid + videoSuffix);
        videoRow.setCover(relatePathOfUser + uuid + "/" + uuid + imgSuffix);
        var duration = jsonNode.path("videoDuration").asInt();
        videoRow.setDuration(duration + "");
        var barrageRootArray = objMapper.createArrayNode();
        for (var i = 0; i <= duration; i++) {
            barrageRootArray.addArray();
        }
        videoRow.setBarrage(barrageRootArray.toString());
        try {
            videoService.addVideoRow(videoRow);
        } catch (Exception e) {
            resultMap.put("upload_result", false);
            resultMap.put("cause_info", "上传视频成功，但是在保存文字信息至数据库时出现错误，可能是因为你输入的视频信息包含不支持的字符");
            resultMap.put("capture_info", e.getMessage());
            return resultMap;
        }
        return resultMap;
    }

    @PostMapping("/register")
    public Map<String, Object> register(@RequestBody @Valid User user) {
        var bCryptPasswordEncoder = new BCryptPasswordEncoder();
        var encoded = bCryptPasswordEncoder.encode(user.getPassword());
        var returnMap = new HashMap<String, Object>();
        if (user.getPassword().equals("") || user.getUserName().equals("")) {
            returnMap.put("result", false);
            returnMap.put("because", "empty of form");
            return returnMap;
        }
        user.setPassword(encoded);
        user.setUserId(commonUtil.generateUserId());
        var map = userService.addUser(user);
        if (map.get("result").equals("true")) {
            returnMap.put("result", true);
            returnMap.put("userId", map.get("userId"));
            returnMap.put("userName", user.getUserName());
        } else {
            returnMap.put("result", false);
            returnMap.put("because", map.get("because"));
        }
        return returnMap;
    }

    @GetMapping("/user/user_video")
    public List<VideoRow> getVideosOfMe(HttpSession session) {
        return videoService.getBaseVideoByAuthor(session.getAttribute(session.getId()) + "");
    }

    @ApiOperation(value = "发送验证码")
    @ApiImplicitParam(name = "userId",value = "账号",required = true)
    @GetMapping("/reset/reset_password/get_veri/{userId}")
    public String sendVerification(@PathVariable String userId){
        var user=userService.findByUserId(userId);
        var jsonObject=new JsonObject();
        if (user==null){
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","找不到该用户");
            return jsonObject.toString();
        }
        var mailStr=user.getMail();
        if (mailStr==null){
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","该账号未设置邮箱");
            return jsonObject.toString();
        }
        if (mailStr.equals("")){
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","该账号未设置邮箱");
            return jsonObject.toString();
        }
        var success=resetPasswordService.newResetRequest(userId,mailStr);
        if (success== NewResetEnum.PASS) {
            jsonObject.addProperty("result", true);
            jsonObject.addProperty("resp","发送成功");
        } else if(NewResetEnum.FORBID==success){
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","剩余次数已用完");
        }else{
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","服务器错误");
        }
        return jsonObject.toString();
    }
    @PostMapping("/reset/reset_password/exec")
    public String resetPassword(@RequestBody Map<String,String> requestData){
        var jsonObject=new JsonObject();
        var user=userService.findByUserId(requestData.get("userId"));
        if (user==null){
            jsonObject.addProperty("result", false);
            jsonObject.addProperty("resp","找不到该用户");
            jsonObject.addProperty("code",4);
            return jsonObject.toString();
        }
        var data=redisVerificationCode.isExist(requestData.get("userId"));
        var calendar = Calendar.getInstance();
        var nowTime=calendar.getTime().getTime();
        if (data.getLatestCodeExpired()<nowTime){
            jsonObject.addProperty("result",false);
            jsonObject.addProperty("resp","验证码错误或已过期");
            jsonObject.addProperty("code",1);
            return jsonObject.toString();
        }
        if (!requestData.get("code").equals(data.getLatestCode())){
            jsonObject.addProperty("result",false);
            jsonObject.addProperty("resp","验证码错误");
            jsonObject.addProperty("code",2);
            return jsonObject.toString();
        }
        if (!data.isValid()){
            jsonObject.addProperty("result",false);
            jsonObject.addProperty("resp","验证码已失效");
            jsonObject.addProperty("code",3);
            return jsonObject.toString();
        }
        userService.resetPassword(requestData.get("userId"),requestData.get("newPassword"));
        data.setValid(false);
        redisVerificationCode.update(data);
        jsonObject.addProperty("result",true);
        jsonObject.addProperty("resp","密码修改成功");
        jsonObject.addProperty("code",0);
        return jsonObject.toString();
    }
}
